﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using MeasureAbstract.IMotionDevice;
using System.Reflection;

namespace MeasureAbstract.Base
{
    public static class TestMode
    {
        /// <summary>
        /// 参数定义 从左至右  运动设备，矢网，起始位置，结束位置，步进长度，频点列表，报告函数
        /// </summary>
        public static void StepMode(IMotionDevice.IMotionDevice MC, IVectorNetworkAnalyzer.IVectorNetworkAnalyzer VNA, double StartPosition, double EndPosition, double StepPosition, List<double> FrequencyList, 
            in Flag Flag,
            Action<MeasurementProcessInformationType, object> Report,
            Dictionary<double, ObservableCollection<DataItem>> DataDictPosition_FrequencyCollection,
            Dictionary<double, ObservableCollection<DataItem>> DataDictFrequency_PositionCollection,
            MeasureData MeasureData
            )
        {
            double Finish = 0;
            double Total = Math.Abs((EndPosition - StartPosition) / StepPosition) + 1;

            //先找到转动轴
            if (MC == null)
            {
                throw new Exception("未找到运动设备!");
            }


            Axis? Axis = null;
            foreach (var axis in MC.Config.Axes)
            {
                if (axis.Selected)
                {
                    Axis = axis;
                    break;
                }
            }
            if (Axis == null)
            {
                throw new Exception("未选择转动轴!");
            }


            if (VNA == null)
            {
                throw new Exception("未找到矢量网络分析仪!");
            }

            //运动至起始点
            MC.Run(Axis.AxisID, StartPosition, Axis.SetSpeed, 1, 1);

            //循环判断是否到位,加入超时设置
            DateTime S = DateTime.Now;
            DateTime E = new DateTime();
            Report.Invoke(MeasurementProcessInformationType.Information, "正在走到起始点……");
            double Time = Math.Abs(Axis.CurrentPosition - StartPosition) / Axis.SetSpeed + 10;
            while (true)
            {
                if (Math.Abs(Axis.CurrentPosition - StartPosition) < 0.01 && Axis.CurrentSpeed == 0)
                {
                    //到达了起始点
                    break;
                }
                E = DateTime.Now;
                if ((E - S).TotalSeconds > Time)
                {
                    //报错
                    Report.Invoke(MeasurementProcessInformationType.Information, $"长时间未走到起点{StartPosition.ToString("F3")}，疑似发生故障，测试终止!");
                    throw new Exception($"长时间未走到起点{StartPosition.ToString("F3")}，疑似发生故障，测试终止!");
                }
                if(Flag.StopFlag)
                {
                    //主动终止测试
                    throw new Exception($"终止测试!");
                }
            }


            //开始测试
            Report.Invoke(MeasurementProcessInformationType.Information, "到达起始点!\n开始进行测试");
            Report.Invoke(MeasurementProcessInformationType.Process, 0.0); // 报告进度



            //步进运动
            //读数->->判断是否结束->运动至下一点》读数->->判断是否结束->运动至下一点》》》
            double StepValue = EndPosition > StartPosition ? Math.Abs(StepPosition) : -Math.Abs(StepPosition);
            double TargetPosition = StartPosition;
            while (true)
            {

                Report.Invoke(MeasurementProcessInformationType.Information, $"正在测量{TargetPosition.ToString("F3")}");

                //所有测量都扫描
                Report.Invoke(MeasurementProcessInformationType.Information, "矢网采集数据...");
                VNA.MeasureOnce();
                VNA.Wait(500);
                

                double RecordPosition = TargetPosition;
                Report.Invoke(MeasurementProcessInformationType.Information, "从矢网读取数据...");

                //依次读取每一组测量的数据，
                if (VNA.SelectedDataFormats.Count > 0)
                {
                    double[] Values = new double[FrequencyList.Count];

                    List<DataItem> Items = new List<DataItem>();
                    for (int i = 0; i < VNA.SelectedDataFormats.Count; i++)
                    {
                        VNA.ReadData(1, VNA.SelectedDataFormats[i], out Values);
                        Type Type = typeof(DataItem);
                        PropertyInfo[] PropertyInfo = Type.GetProperties();
                        //通过特性值给DataItem赋值
                        PropertyInfo AimProperty = PropertyInfo[0];
                        foreach (PropertyInfo Property in PropertyInfo)
                        {
                            var attr = Property.GetCustomAttribute<DisplayNameAttribute>(false);
                            if (attr == null) continue;
                            if (attr.DisplayName == VNA.SelectedDataFormats[i].Replace(" ", ""))
                            {
                                AimProperty = Property;
                                break;
                            }
                        }
                        Application.Current.Dispatcher.Invoke(() =>
                        {
                            DataManage.AddOrUpdateFrequencySpectrumToPositionBaseDict(RecordPosition, Values.ToList(), FrequencyList.ToList(), (s, v) =>
                            {
                                AimProperty.SetValue(s, v);
                            }, ref DataDictPosition_FrequencyCollection);
                            DataManage.AddOrUpdateFrequencySpectrumToFrequencyBaseDict(RecordPosition, Values.ToList(), FrequencyList.ToList(), (s, v) =>
                            {
                                AimProperty.SetValue(s, v);
                            }, ref DataDictFrequency_PositionCollection);
                        });

                        DataManage.BuildFrequencySpectrumDataItemList(TargetPosition, FrequencyList.ToList(), Values.ToList(), ref Items, (s, v) =>
                        {
                            AimProperty.SetValue(s, v);
                        });
                    }
                    if (MeasureData.DataItems == null)
                    {
                        MeasureData.DataItems = new ObservableCollection<DataItem>();
                    }
                    foreach (var v in Items)
                    {
                        MeasureData.DataItems.Add(v);
                    }

                }

                Finish += 1;
                Report.Invoke(MeasurementProcessInformationType.Process, Finish / Total * 100.0); //报告测量进度 

                //判断是否结束
                //if (Math.Abs(Axis.CurrentPosition - EndPosition) < Math.Abs(Axis.Accuracy * 2))
                if (Math.Abs(Axis.CurrentPosition - EndPosition) <  0.01 && Axis.CurrentSpeed == 0)
                {
                    //测试结束
                    Report.Invoke(MeasurementProcessInformationType.Information, "测试结束!");

                    break;
                }

                //运动至下一点
                TargetPosition = TargetPosition + StepValue;
                Report.Invoke(MeasurementProcessInformationType.Information, $"等待运动至{TargetPosition}...");

                if (StepValue > 0)
                {
                    if (TargetPosition > EndPosition)
                    {
                        TargetPosition = EndPosition;
                    }
                }
                else
                {
                    if (TargetPosition < EndPosition)
                    {
                        TargetPosition = EndPosition;
                    }
                }

                MC.Run(Axis.AxisID, TargetPosition, Axis.SetSpeed, 1, 1);
                Time = Math.Abs(StepValue) / Math.Abs(Axis.SetSpeed) + 10;
                S = DateTime.Now;
                //等待达位
                while (true)
                {
                    //if (Math.Abs(TargetPosition - Axis.CurrentPosition) <= Math.Abs(Axis.Accuracy * 2))
                    if (Math.Abs(TargetPosition - Axis.CurrentPosition) < 0.01 && Axis.CurrentSpeed == 0)
                    {
                        Report.Invoke(MeasurementProcessInformationType.Information, $"到达{TargetPosition}");

                        break;
                    }
                    E = DateTime.Now;
                    if ((E - S).TotalSeconds > Time)
                    {
                        //报错
                        Report.Invoke(MeasurementProcessInformationType.Information, $"长时间未走到点{TargetPosition.ToString("F3")}，疑似发生故障，测试终止!");
                        throw new Exception($"长时间未走到点{TargetPosition.ToString("F3")}，疑似发生故障，测试终止!");
                    }
                    if (Flag.StopFlag)
                    {
                        //主动终止测试
                        throw new Exception($"终止测试!");
                    }
                }

            }
        }
        public static void StepMode_Debug(IMotionDevice.IMotionDevice MC, IVectorNetworkAnalyzer.IVectorNetworkAnalyzer VNA, double StartPosition, double EndPosition, double StepPosition, List<double> FrequencyList,
            in Flag Flag, 
            Action<MeasurementProcessInformationType, object> Report,
            Dictionary<double, ObservableCollection<DataItem>> DataDictPosition_FrequencyCollection,
            Dictionary<double, ObservableCollection<DataItem>> DataDictFrequency_PositionCollection,
            MeasureData MeasureData
            )
        {
            double Finish = 0;
            double Total = Math.Abs((EndPosition - StartPosition) / StepPosition) + 1;

            //先找到转动轴
            if (MC == null)
            {
                throw new Exception("未找到运动设备!");
            }


            Axis? Axis = null;
            foreach (var axis in MC.Config.Axes)
            {
                if (axis.Selected)
                {
                    Axis = axis;
                    break;
                }
            }
            if (Axis == null)
            {
                throw new Exception("未选择转动轴!");
            }


            if (VNA == null)
            {
                throw new Exception("未找到矢量网络分析仪!");
            }

            //运动至起始点
            //MC.Run(Axis.AxisID, StartPosition, Axis.SetSpeed, 1, 1);
            Axis.CurrentPosition = StartPosition;
            Thread.Sleep(1000);

            //循环判断是否到位,加入超时设置
            DateTime S = DateTime.Now;
            DateTime E = new DateTime();
            Report.Invoke(MeasurementProcessInformationType.Information, "正在走到起始点……");
            double Time = Math.Abs(Axis.CurrentPosition - StartPosition) / Axis.SetSpeed + 10;
            while (true)
            {
                if (Math.Abs(Axis.CurrentPosition - StartPosition) < 0.01 && Axis.CurrentSpeed == 0)
                {
                    //到达了起始点
                    break;
                }
                E = DateTime.Now;
                if ((E - S).TotalSeconds > Time)
                {
                    //报错
                    throw new Exception($"长时间未走到起点{StartPosition.ToString("F3")}，疑似发生故障，测试终止!");
                }
                if(Flag.StopFlag)
                {
                    throw new Exception($"测试终止!");
                }
            }


            //开始测试
            Report.Invoke(MeasurementProcessInformationType.Information, "到达起始点!\n开始进行测试");
            Report.Invoke(MeasurementProcessInformationType.Process, 0.0); // 报告进度



            //步进运动
            //读数->->判断是否结束->运动至下一点》读数->->判断是否结束->运动至下一点》》》
            double StepValue = EndPosition > StartPosition ? Math.Abs(StepPosition) : -Math.Abs(StepPosition);
            double TargetPosition = StartPosition;
            while (true)
            {

                if (Flag.StopFlag)
                {
                    throw new Exception($"测试终止!");
                }
                //所有测量都扫描
                //VNA.MeasureOnce();
                //VNA.Wait(500);

                Report.Invoke(MeasurementProcessInformationType.Information, $"正在测量{TargetPosition.ToString("F3")}");

                double RecordPosition = TargetPosition;

                //依次读取每一组测量的数据，
                if (VNA.SelectedDataFormats.Count > 0)
                {
                    double[] Values = new double[FrequencyList.Count];

                    List<DataItem> Items = new List<DataItem>();
                    for (int i = 0; i < VNA.SelectedDataFormats.Count; i++)
                    {
                        //VNA.ReadData(1, VNA.SelectedDataFormats[i], out Values);
                        for (int k = 0; k < Values.Length; k++)
                        {
                            Values[k] = new Random().Next(1, 20);
                        }



                        Type Type = typeof(DataItem);
                        PropertyInfo[] PropertyInfo = Type.GetProperties();
                        //通过特性值给DataItem赋值
                        PropertyInfo AimProperty = PropertyInfo[0];
                        foreach (PropertyInfo Property in PropertyInfo)
                        {
                            var attr = Property.GetCustomAttribute<DisplayNameAttribute>(false);
                            if (attr == null) continue;
                            if (attr.DisplayName == VNA.SelectedDataFormats[i].Replace(" ", ""))
                            {
                                AimProperty = Property;
                                break;
                            }
                        }
                        Application.Current.Dispatcher.Invoke(() =>
                        {
                            DataManage.AddOrUpdateFrequencySpectrumToPositionBaseDict(RecordPosition, Values.ToList(), FrequencyList.ToList(), (s, v) =>
                            {
                                AimProperty.SetValue(s, v);
                            }, ref DataDictPosition_FrequencyCollection);
                            DataManage.AddOrUpdateFrequencySpectrumToFrequencyBaseDict(RecordPosition, Values.ToList(), FrequencyList.ToList(), (s, v) =>
                            {
                                AimProperty.SetValue(s, v);
                            }, ref DataDictFrequency_PositionCollection);
                        });

                        DataManage.BuildFrequencySpectrumDataItemList(TargetPosition, FrequencyList.ToList(), Values.ToList(), ref Items, (s, v) =>
                        {
                            AimProperty.SetValue(s, v);
                        });
                    }
                    if (MeasureData.DataItems == null)
                    {
                        MeasureData.DataItems = new ObservableCollection<DataItem>();
                    }
                    foreach (var v in Items)
                    {
                        MeasureData.DataItems.Add(v);
                    }

                }

                Finish += 1;
                Report.Invoke(MeasurementProcessInformationType.Process, Finish / Total * 100.0); //报告测量进度 
                //判断是否结束
                if (Math.Abs(Axis.CurrentPosition - EndPosition) < Math.Abs(Axis.Accuracy * 2))
                {
                    //测试结束
                    break;
                }

                //运动至下一点
                TargetPosition = TargetPosition + StepValue;
                if (StepValue > 0)
                {
                    if (TargetPosition > EndPosition)
                    {
                        TargetPosition = EndPosition;
                    }
                }
                else
                {
                    if (TargetPosition < EndPosition)
                    {
                        TargetPosition = EndPosition;
                    }
                }

                //MC.Run(Axis.AxisID, TargetPosition, Axis.SetSpeed, 1, 1);
                Axis.CurrentPosition = TargetPosition;
                Thread.Sleep(1000);
                //等待达位
                while (true)
                {
                    if (Math.Abs(TargetPosition - Axis.CurrentPosition) <= Math.Abs(Axis.Accuracy * 2))
                    {
                        break;
                    }
                    if (Flag.StopFlag)
                    {
                        throw new Exception($"测试终止!");
                    }
                }
            }
        }
    }
}
